package br.com.gkarian.mydesk.controller;

import static br.com.caelum.vraptor.view.Results.json;

import org.apache.log4j.Logger;

import br.com.caelum.vraptor.Get;
import br.com.caelum.vraptor.Post;
import br.com.caelum.vraptor.Put;
import br.com.caelum.vraptor.Resource;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.Validator;
import br.com.caelum.vraptor.validator.ValidationException;
import br.com.caelum.vraptor.validator.ValidationMessage;
import br.com.gkarian.mydesk.anotacoes.AlteracaoIndevida;
import br.com.gkarian.mydesk.anotacoes.RestritoUsuario;
import br.com.gkarian.mydesk.model.Usuario;
import br.com.gkarian.mydesk.services.interfaces.UsuarioService;
import br.com.gkarian.mydesk.web.UsuarioWeb;

@Resource
public class UsuarioController {

	private static final Logger LOG = Logger.getLogger(UsuarioController.class);

	private Result result;
	private Validator validator;
	private UsuarioService usuarioService;
	private UsuarioWeb usuarioWeb;

	public UsuarioController(Result result, Validator validator,
			UsuarioService usuarioService, UsuarioWeb usuarioWeb) {
		this.result = result;
		this.validator = validator;
		this.usuarioService = usuarioService;
		this.usuarioWeb = usuarioWeb;
	}

	@Get("/cadastrar")
	public void cadastrarUsuario() {
	}

	@Post("/cadastrarUsuario")
	public void cadastrarUsuario(Usuario usuario) {
		validator.validate(usuario);
		validator.onErrorRedirectTo(this).cadastrarUsuario();
		
		try {
			if (usuarioService.isExisteLogin(usuario.getLogin())) {
				LOG.info("Login já cadastrado = " + usuario.getLogin());
				validator.add(new ValidationMessage("login.ja.cadastrado",
						"usuario.login"));
				validator.onErrorRedirectTo(this).cadastrarUsuario();
			}

			usuarioService.adicionar(usuario);

		} catch (ValidationException e) {
			throw e;
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
			validator.add(new ValidationMessage("erro.inesperado", "error"));
			validator.onErrorRedirectTo(this).cadastrarUsuario();
		}

		result.redirectTo(MainController.class).index();
	}

	@Post("/login")
	public void login(Usuario usuario) {
		Usuario carregado;
		try {
//			if (1 == 1)
//				throw new Exception("aaaaaaaaaaaaaaaaaaa");

			carregado = usuarioService.carregar(usuario);

			if (carregado == null) {
				LOG.info("Não foi encontrado nenhum usuario de login = " + usuario.getLogin());
				validator.add(new ValidationMessage("login.ou.senha.invalido",
						"usuario.login"));
				result.include("flagLogin", "true");
				validator.onErrorRedirectTo(MainController.class).index();
			}

			usuarioWeb.login(carregado);
		} catch (ValidationException e) {
			throw e;
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
			result.include("windowError", "true");
			validator.add(new ValidationMessage("erro.inesperado", "error"));
			validator.onErrorRedirectTo(MainController.class).index();
		}

		result.redirectTo(MainController.class).index();
	}

	@Get("/logout")
	public void logout() {
		if (usuarioWeb.getLogado() != null) {
			LOG.info("Deslogando usuario de ID [" + usuarioWeb.getLogado().getId() + "]");
			usuarioWeb.logout();
		}
		result.redirectTo(MainController.class).index();
	}

	@Get("/verificarDisponibilidadeLogin/{login}")
	public void verificarDisponibilidadeLogin(String login) {
		try {
			boolean resultado = usuarioService.isExisteLogin(login);
			LOG.info("Verificacao da disponibilidade do login [" + login + "] retornou: " + resultado);
			if (resultado) {
				result.use(json()).withoutRoot().from(true).serialize();
				return;
			}

		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
			// TODO: redirecionar para tela de erro;
		}
		result.use(json()).withoutRoot().from(false).serialize();
	}

	@RestritoUsuario
	@Get("/usuario/editaUsuario")
	public void editarUsuario() {
		result.include("usuario", usuarioWeb.getLogado());
	}

	@RestritoUsuario
	@AlteracaoIndevida
	@Put("/usuario/editaUsuario")
	public void editarUsuario(Usuario usuario) {
		validator.validate(usuario);
		validator.onErrorRedirectTo(this).editarUsuario();

		try {
			usuarioService.atualizar(usuario);
			this.usuarioWeb.setLogado(usuario);
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
			// TODO: redirecionar para tela de erro;
		}

		result.redirectTo(MainController.class).index();
	}

}
